/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package views;

import chatsystem.ChatSystemControler;
import chatsystem.ChatSystemModel;
import chatsystem.User;
import chatsystem.patternObserver.Observer;
import chatsystem.patternState.OfflineState;
import chatsystem.patternState.OnlineState;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 *
 * @author Diane
 */
public class ChatSystemView extends JFrame implements Observer, WindowListener {

    private JPanel contentPane;
    private JPanel panelConnexion;
    private JPanel panelOnline;

    // Composants du panel Connexion
    private JTextField textFieldUsername;
    private JButton btnConnect;

    // Composants du panel Online
    private JLabel username;
    private JButton btnDisconnect;
    private JButton btnNewTalk;
    private JList listConnectedUsers;
    private JLabel labelNotifications;
    private JScrollPane jScrollPane1;
    private JTextArea notifications;
    
    // Instance de l'objet contrôleur
    private ChatSystemControler csc;

    public ChatSystemView(final ChatSystemControler csc) {

        this.csc = csc;
        this.setSize(200,500);
        this.setTitle("ChatSystem");        
        initComponents();

        this.getRootPane().setDefaultButton(btnConnect);

        this.csc = csc;
        this.setContentPane(contentPane);
        this.setVisible(true);
    }

    private void initComponents() {

        addWindowListener(this);
        
        contentPane = new JPanel(new BorderLayout());
        setBounds(100, 100, 450, 300);
        this.panelConnexion = this.construirePanelConnexion();

        contentPane.add(panelConnexion, BorderLayout.NORTH);
    }

    private JPanel construirePanelConnexion() {
        
        JPanel p = new JPanel(new GridLayout(3,1));

        JLabel lblNewLabel_1 = new JLabel("Nom d'utilisateur :");
        p.add(lblNewLabel_1);

        textFieldUsername = new JTextField("");

        textFieldUsername.addKeyListener(new KeyAdapter() {
                @Override
                public void keyTyped(KeyEvent event) {                             
                    if (textFieldUsername.getText().length() > 0) {
                        btnConnect.setEnabled(true);
                    } else {
                        btnConnect.setEnabled(false);
                    }
                }});

        btnConnect = new JButton("Se connecter");
        btnConnect.setEnabled(false);
        btnConnect.addActionListener(new ButtonListener());

        p.add(textFieldUsername);
        p.add(btnConnect);

        return p;
    }

    private void construirePanelOnline() {

        panelOnline = new JPanel();
        contentPane.add(panelOnline, BorderLayout.NORTH);
        panelOnline.setLayout(new GridLayout(2, 2, 1, 1));

        username = new JLabel("");
        panelOnline.add(username);

        btnDisconnect = new JButton("Se déconnecter");
        btnDisconnect.addActionListener(new ButtonListener());
        panelOnline.add(btnDisconnect);

        btnNewTalk = new JButton("Nouvelle conversation");
        btnNewTalk.setEnabled(false);
        btnNewTalk.addActionListener(new ButtonListener());
        panelOnline.add(btnNewTalk);

        listConnectedUsers = new JList();
        listConnectedUsers.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        listConnectedUsers.setSelectedIndex(0);

        listConnectedUsers.addListSelectionListener(new ListListener());

        JScrollPane listScroller = new JScrollPane(listConnectedUsers);
        listScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        
        contentPane.add(listScroller, BorderLayout.CENTER);

        labelNotifications = new JLabel("Notifications");
        
        jScrollPane1 = new JScrollPane();
        jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        jScrollPane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        
        notifications = new JTextArea();
        notifications.setRows(5);
        
        jScrollPane1.setViewportView(notifications);
        
        //contentPane.add(labelNotifications, BorderLayout.SOUTH);
        contentPane.add(jScrollPane1, BorderLayout.SOUTH);
        notifications.setEditable(false);
        notifications.append("Notifications :\n");
        
        this.setVisible(true);
    }

    public void windowOpened(WindowEvent e) {
        
    }

    public void windowClosing(WindowEvent e) {
        try {
            // TODO Demander confirmation de se déconnecter        
            csc.disconnect();
        } catch (Exception ex) {
            System.out.println(ex);
        }
        System.exit(0);
    }

    public void windowClosed(WindowEvent e) {

    }

    public void windowIconified(WindowEvent e) {
        
    }

    public void windowDeiconified(WindowEvent e) {
        
    }

    public void windowActivated(WindowEvent e) {
        
    }

    public void windowDeactivated(WindowEvent e) {
        
    }

    public void notifyHello(User new_user) {
        notifications.append(new_user.getName() + " vient de se connecter.\n");        
    }
    
    public void notifyBye(User old_user) {
        notifications.append(old_user.getName() + " vient de se déconnecter.\n");
    }

    /* Listener de sélection de la liste */
    class ListListener implements ListSelectionListener{

        public void valueChanged(ListSelectionEvent e) {

            if (e.getValueIsAdjusting() == false) {
                if (listConnectedUsers.getSelectedIndex() == -1) {
                    //No selection, disable new talk button.
                    btnNewTalk.setEnabled(false);
                } else {
                    //Selection, enable the fire button.
                    btnNewTalk.setEnabled(true);
                }
            }
        }
    }

    /* Listener du bouton Se connecter */
    class ButtonListener implements ActionListener{

        public void actionPerformed(ActionEvent e) {
            // CLIC sur le bouton Connect
            if (e.getSource() == btnConnect) {
                try {
                    csc.connect(textFieldUsername.getText());
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }

            // CLIC sur le bouton Disconnect
            if (e.getSource() == btnDisconnect) {
                try {
                   csc.disconnect();         
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }

            // CLIC sur le bouton New Talk
            if (e.getSource() == btnNewTalk) {
                try {
                    int[] selectedIndex = listConnectedUsers.getSelectedIndices();

                    for (User u : getUsersByIndex(selectedIndex)) {
                        System.out.println("nouvelle conversation avec : "+u.getName());
                    }
                    csc.createNewTalk(getUsersByIndex(selectedIndex));
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }
        }
    }

    private ArrayList<User> getUsersByIndex(int[] selectedIndex) {
        ArrayList<User> selectedUsers = new ArrayList<User>();

        for (int i : selectedIndex) {
            String name = (String) listConnectedUsers.getModel().getElementAt(i);
            selectedUsers.add(csc.getUserByName(name));
        }

        return selectedUsers;
    }

    /*
     * Implémentation du Pattern Observer
     */
    public void update(ChatSystemModel cs) {

        // Mise à jour de la liste de contacts
        
        // Affichage de l'IHM dans l'état Online
        if (cs.getEtat() instanceof OnlineState) {
            contentPane.removeAll();
            construirePanelOnline();

            listConnectedUsers.setModel(cs);
            username.setText(cs.getMySelf().getName());

            this.repaint();
            this.setVisible(true);        
        } else

        // Affichage de l'IHM dans l'état Offline
        if (cs.getEtat() instanceof OfflineState) {
            contentPane.removeAll();
            contentPane.add(panelConnexion, BorderLayout.NORTH);
            
            this.repaint();
            this.setVisible(true);
        }
    }
}
